package com.jjc.android.base

import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ActivityInfo
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import com.jjc.android.R
import com.jjc.android.dialog.LoadingDialog
import com.jjc.android.util.MultiLanguageUtil
import com.jjc.android.util.UIStatusBarHelper
import com.jjc.android.view.status.OnStatusChildClickListener
import com.jjc.android.view.status.StatusLayoutManager
import com.lzy.okgo.OkGo
import org.greenrobot.eventbus.EventBus
import java.io.Serializable
import java.lang.ref.WeakReference


abstract class BaseActivity : AppCompatActivity() {

    @SuppressLint("SourceLockedOrientationActivity")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        this.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        if(null != savedInstanceState){
            setupArguments(savedInstanceState);
        }else{
            if(intent !=null){
                setupArguments(intent.extras);
            }
        }
        loadContentView()
//        window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
        if (isHaveEventBus()) {
            if (!EventBus.getDefault().isRegistered(this)) {
                EventBus.getDefault().register(this)
            }
        }
        findViewById<View?>(R.id.iv_bar_back)?.setOnClickListener {
            onBackBtnClick()
        }

        initView(savedInstanceState)
        onStatusBarColor()
    }

    protected open fun onBackBtnClick(){
        finish()
    }

    protected open fun loadContentView(){
        if(layoutId>0){
            setContentView(layoutId)
        }else{
            getContentView()?.let {
                setContentView(it)
            }
        }
    }

    protected var statusLayoutManager: StatusLayoutManager? = null

    fun showLoadingView(wrapperView:View,emptyText:String = getString(R.string.status_layout_manager_empty)){
        if(statusLayoutManager==null){
            statusLayoutManager = StatusLayoutManager.Builder(wrapperView)
                .setDefaultEmptyText(emptyText)
                .setDefaultEmptyClickViewVisible(false)
                .setDefaultErrorClickViewVisible(false)
                .setOnStatusChildClickListener(object : OnStatusChildClickListener {
                    override fun onEmptyChildClick(view: View?) {
                        fetchPageInfo()
                    }

                    override fun onErrorChildClick(view: View?) {
                        fetchPageInfo()
                    }

                    override fun onCustomerChildClick(view: View?) {
                        fetchPageInfo()
                    }
                })
                .build()
        }
        statusLayoutManager?.showLoadingLayout()
    }

    fun hideLoadingView(){
        statusLayoutManager?.showSuccessLayout()
    }

    open fun showEmptyView(emptyText:String = getString(R.string.status_layout_manager_empty)){
        statusLayoutManager?.showEmptyLayout(emptyText)
    }

    fun showErrorView(errorText:String? = getString(R.string.net_error_txt)){
        statusLayoutManager?.showErrorLayout(errorText)
    }

    protected open fun fetchPageInfo(){

    }

    protected open fun getContentView():View?{
        return null
    }
    protected abstract val layoutId: Int
    protected abstract fun initView(savedInstanceState: Bundle?)
    protected open fun isFullscreenStatus():Boolean = true

    protected open fun isStatusWhiteModel():Boolean = false
    protected open fun onStatusBarColor() {
        if(isFullscreenStatus()){
            findViewById<View?>(R.id.toolbar)?.let {
                UIStatusBarHelper.setStatusBarPaddingAndHeight(it)
            }
            UIStatusBarHelper.translucent(this)
        }else{
            UIStatusBarHelper.setStatusbarBackground(this,ContextCompat.getColor(this,R.color.white))
        }
        if(isStatusWhiteModel()){
            UIStatusBarHelper.setStatusBarDarkMode(this)
        }else{
            UIStatusBarHelper.setStatusBarLightMode(this)
        }
    }

    protected fun setActivityTitle(@StringRes titleRes: Int) {
        setActivityTitle(getString(titleRes))
    }

    protected fun setActivityTitle(titleStr: String) {
        val titleText: TextView? = findViewById(R.id.tv_bar_title)
        if (titleText != null) {
            titleText.text = titleStr
        }
    }

    private var progressDialog:LoadingDialog? = null

    fun showLoadingDialog(message:String = getString(R.string.status_layout_manager_loading)){
        try {
            if(progressDialog == null){
                progressDialog = LoadingDialog(this,message)
            }
            progressDialog?.show()

        }catch (e:Exception){
            e.printStackTrace()
        }
    }

    fun hideLoadingDialog(){
        try {
            if(progressDialog!=null&&progressDialog!!.isShowing){
                progressDialog?.dismiss()
            }
        }catch (e:Exception){
            e.printStackTrace()
        }
    }



    protected open fun isHaveEventBus(): Boolean {
        return false
    }

    override fun onStop() {
        hideLoadingDialog()
        super.onStop()

    }

    override fun onDestroy() {
        super.onDestroy()
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
        OkGo.getInstance().cancelTag(this)
    }

    /**
     * Fragment的添加
     * @param aClass 相应的Fragment对象的getClass
     * @param containerId 容器的id
     * @param args 需要传值的话可将bundle填入  不需要传值就填null
     */
    protected open fun addFragment(manager: FragmentManager, aClass: Class<out BaseFragment?>, containerId: Int, args: Bundle? = null):Fragment? {
        val tag = aClass.name
        var fragment: Fragment? = manager.findFragmentByTag(tag)
        val transaction: FragmentTransaction = manager.beginTransaction() // 开启一个事务
        if (fragment == null) { // 没有添加
            try {
                fragment = aClass.newInstance()
                transaction.add(containerId, fragment!!, tag)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        } else {
            if (fragment.isAdded) {
                if (fragment.isHidden) {
                    transaction.show(fragment)
                }
            } else {
                transaction.add(containerId, fragment, tag)
            }
        }
        if (fragment != null) {
            fragment.arguments = args
            hideBeforeFragment(manager, transaction, fragment)
            transaction.commitAllowingStateLoss()
        }
        return fragment
    }


    /**
     * 除当前 fragment 以外的所有 fragment 进行隐藏
     *
     * @param manager
     * @param transaction
     * @param currentFragment
     */
    protected fun hideBeforeFragment(manager: FragmentManager, transaction: FragmentTransaction, currentFragment: Fragment) {
        val fragments: List<Fragment> = manager.fragments
        for (fragment in fragments) {
            if (fragment !== currentFragment && !fragment.isHidden) {
                transaction.hide(fragment)
            }
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        onSaveIntent(outState)
    }

    protected open fun onSaveIntent(savedInstanceState: Bundle) {
        if (intent != null) {
            val bundle = intent.extras
            if (bundle != null) {
                val keySet = bundle.keySet()
                for (key in keySet) {
                    val value = bundle[key]
                    if (value != null) {
                        when(value){
                            is String->savedInstanceState.putString(key, value)
                            is Int->savedInstanceState.putInt(key, value)
                            is Boolean->savedInstanceState.putBoolean(key, value)
                            is Float->savedInstanceState.putFloat(key, value)
                            is Long->savedInstanceState.putLong(key, value)
                            is Parcelable ->savedInstanceState.putParcelable(key, value)
                            is Serializable ->savedInstanceState.putSerializable(key, value)
                            else-> savedInstanceState.putString(key, value.toString())
                        }
                    }
                }
            }
        }
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        super.onRestoreInstanceState(savedInstanceState)
        setupArguments(savedInstanceState)
    }

    protected open fun setupArguments(args: Bundle?) {}

    private val tagInstances:HashMap<String,WeakReference<Any>> by lazy {
        HashMap()
    }

    fun <T> getTagInstances(index:String):T?{
        return tagInstances[index]?.get() as? T
    }

    fun saveTagInstances(index:String,value:Any){
        tagInstances.put(index, WeakReference(value))
    }

    override fun attachBaseContext(newBase: Context?) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
            val res = newBase!!.resources
            val config = res.configuration
            val newContext = newBase.createConfigurationContext(config)
            super.attachBaseContext(MultiLanguageUtil.getInstance().attachBaseContext(newContext))
        } else {
            super.attachBaseContext(MultiLanguageUtil.getInstance().attachBaseContext(newBase))
        }
    }

}